/*
 * Player.java - A class for a player
 * 
 * Updated on August 18, 2009 by Ming Chow
 */

package game.mchow.beamwars;

import java.awt.*;
import java.security.SecureRandom;

public class Player
{
	public static final int NUM_ALGORITHMS = 2;
	public static final int NEUTRAL = 0;
	public static final int UP = 1;
	public static final int DOWN = 2;
	public static final int LEFT = 3;
	public static final int RIGHT = 4;	
	private int id, score, numWins, lastInput, lastX, lastY, algorithm;
	private boolean human, eliminated;
	private Color color;
	private BeamWars gameCopy;

	public Player (int id, Color color, boolean human, BeamWars gameCopy)
	{
		this.id = id;
		this.color = color;
		this.human = human;
		this.gameCopy = gameCopy;
		score = 0;
		numWins = 0;
		reset();
	}
	
	// Start player on random position on the grid
	public void reset()
	{
		SecureRandom random = new SecureRandom();

		eliminated = false;
		boolean done = false;
		while (!done) {
			int x = random.nextInt(gameCopy.getGridWidth());
			int y = random.nextInt(gameCopy.getGridHeight());
			if (gameCopy.getMark(x, y) == 0) {
				gameCopy.setMark(x, y, this);
				lastX = x;
				lastY = y;
				if (x <= gameCopy.getGridWidth() / 2) {
					lastInput = RIGHT;
				}
				else {
					lastInput = LEFT;
				}
				done = true;
			}
		}
		
		// Determine how "smart" this computer player is
		if (this.human) {
			algorithm = 0;
		}
		else {
			//algorithm = random.nextInt(NUM_ALGORITHMS) + 1; // for now
			algorithm = 2;
		}
	}

	public int getId() {
		return id;
	}

	public int getScore() {
		return score;
	}

	public void win (int score) {
		this.score += score;
		this.numWins++;
	}

	public int getNumWins() {
		return numWins;
	}

	public boolean isHuman() {
		return human;
	}

	public boolean isEliminated() {
		return eliminated;
	}

	public void eliminate() {
		this.eliminated = true;
	}

	public Color getColor() {
		if (eliminated) {
			return Color.BLACK;
		}
		return color;
	}

	public int getLastInput() {
		return lastInput;
	}

	public void setLastInput(int lastInput) {
		this.lastInput = lastInput;
	}
		
	public void move()
	{
		int tempX = -1, tempY = -1;
		
		switch (lastInput) {
			case UP:
				tempX = lastX;
				tempY = lastY - 1;
				break;
			case DOWN:
				tempX = lastX;
				tempY = lastY + 1;
				break;
			case LEFT:
				tempX = lastX - 1;
				tempY = lastY;
				break;
			case RIGHT:
				tempX = lastX + 1;
				tempY = lastY;
				break;
		}
		if (gameCopy.setMark(tempX, tempY, this)) {
			lastX = tempX;
			lastY = tempY;
		}
	}
	
	public void setDirection (int direction)
	{
		switch (direction) {
			case UP:
				lastInput = UP;
				break;
			case DOWN:
				lastInput = DOWN;
				break;
			case LEFT:
				lastInput = LEFT;
				break;
			case RIGHT:
				lastInput = RIGHT;
		}
	}
	
	public void update()
	{
		SecureRandom random = new SecureRandom();
		int tempX = -1, tempY = -1;
		
		if (!human) {
			switch (algorithm) {
				case 0: // Random walk with kamikaze; really dumb
					setDirection(random.nextInt(4) + 1);
					break;
				case 1: // Random walk; can't go back
					boolean done = false;
					int move = 0;
					while (!done) {
						move = random.nextInt(4) + 1;
						if (Math.abs(move - lastInput) != 1) {
							done = true;
						}
					}
					switch (move) {
						case UP:
							tempX = lastX;
							tempY = lastY - 1;
							break;
						case DOWN:
							tempX = lastX;
							tempY = lastY + 1;
							break;
						case LEFT:
							tempX = lastX - 1;
							tempY = lastY;
							break;
						case RIGHT:
							tempX = lastX + 1;
							tempY = lastY;
							break;
					}
					if (gameCopy.getMark(tempX, tempY) == 0) {
						setDirection(move);
						done = true;
					}
					else {
						setDirection(lastInput);
					}
					break;
				case 2: // Look ahead; still dependent on random
					switch (lastInput) {
						case UP:
							tempX = lastX;
							tempY = lastY - 1;
							break;
						case DOWN:
							tempX = lastX;
							tempY = lastY + 1;
							break;
						case LEFT:
							tempX = lastX - 1;
							tempY = lastY;
							break;
						case RIGHT:
							tempX = lastX + 1;
							tempY = lastY;
							break;
					}
					int result = gameCopy.getMark(tempX, tempY);
					if (result != 0) {
						if (random.nextInt(2) == 0 &&  lastInput == UP || lastInput == DOWN) {
							lastInput = LEFT;
						}
						else {
							lastInput = RIGHT;
						}
					}
					if (result != 0) {
						if (random.nextInt(2) == 0 &&  lastInput == LEFT || lastInput == RIGHT) {
							lastInput = UP;
						}
						else {
							lastInput = DOWN;
						}
					}

					break;
			}
		}
	}
}
